﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace SDT.Libraries.Utilities
{
    /// <summary>
    /// Class provides methods for working with image stream.
    /// </summary>
	public class ImageHelper
	{
		/// <summary>
		/// Get width and height of an image.
		/// </summary>
		/// <returns>Return false if process unsuccessful and true for successful processed.</returns>
		public static bool GetSize(System.IO.Stream stream, out int width, out int height)
		{
			width = height = 0;
			try
			{
				using(System.Drawing.Image img = System.Drawing.Image.FromStream(stream))
				{
					width = img.Width;
					height = img.Height;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}

		/// <summary>
		/// Resize dimensions of an image
		/// </summary>
        /// <param name="MaxWidth">MaxWidth for output image</param>
		/// <param name="MaxHeight">MaxHeight for output image</param>
		/// <param name="stream">Stream to the image</param>
		/// <param name="NewFileName">Filename for saving</param>
		public static void ResizeImage(int MaxWidth, int MaxHeight, System.IO.Stream stream, string NewFileName)
		{
			// load up the image, figure out a "best fit" resize,
			// and then save that new image
			Bitmap OriginalBmp = 
				(System.Drawing.Bitmap)Image.FromStream(stream).Clone();
			Size ResizedDimensions = 
				GetDimensions(MaxWidth, MaxHeight, ref OriginalBmp);
			Bitmap NewBmp = new Bitmap(OriginalBmp, ResizedDimensions);
        
			string ext = System.IO.Path.GetExtension(NewFileName).ToUpper();
			switch (ext) 
			{
				case ".JPG":
					NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
					break;
				case ".GIF":
					NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Gif);
					break;
				case ".PNG":
					NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Png);
					break;
				case ".BMP":
					NewBmp.Save(NewFileName, System.Drawing.Imaging.ImageFormat.Bmp);
					break;
			}
		}

        public static bool IsValidFileType(string fileName)
        {
            string ext = System.IO.Path.GetExtension(fileName).ToUpper();
            switch (ext)
            {
                case ".JPG":
                    return true;
                case ".GIF":
                    return true;
                case ".PNG":
                    return true;
                case ".BMP":
                    return true;
            }

            return false;
        }
        //Add by sunv
        public static bool IsValidImage(string fileName)
        {
            Boolean retVal = true;
            try
            {
                System.Drawing.Image img = System.Drawing.Image.FromFile(fileName);
                img.Dispose();
            }
            catch
            {
                File.Delete(fileName);
                retVal = false;
            }
            return retVal;
        }
        public static bool CheckSize(string fileName, long lsize)
        {
            FileInfo file = new FileInfo(fileName);
            if (file.Length > 1024 * lsize)
            {
                return true;
            }
            else
            { return false; }
        }
        // end sunv
        /// <summary>
        /// Get the best size for an image.
        /// </summary>
        /// <returns></returns>
		public static Size GetDimensions(int MaxWidth, int MaxHeight, ref Bitmap Bmp)
		{
			int Width;
			int Height;
			float Multiplier;

			Height = Bmp.Height;
			Width = Bmp.Width;

			// this means you want to shrink an image that is already shrunken!
			if (Height <= MaxHeight && Width <= MaxWidth)
				return new Size(Width, Height);

			// check to see if we can shrink it width first
			Multiplier = (float)((float)MaxWidth / (float)Width);
			if ((Height * Multiplier)<= MaxHeight)
			{
				Height = (int)(Height * Multiplier);
				return new Size(MaxWidth, Height);
			}

			// if we can't get our max width, then use the max height
			Multiplier = (float)MaxHeight / (float)Height;
			Width = (int)(Width * Multiplier);
			return new Size(Width, MaxHeight);
		}

        public static byte[] ResizeFromByteArray(int MaxSideSize, Byte[] byteArrayIn, string fileName)
        {
            byte[] byteArray = null;  // really make this an error gif
            MemoryStream ms = new MemoryStream(byteArrayIn);
            byteArray = ResizeFromStream(MaxSideSize, ms, fileName);

            return byteArray;
        }

        /// <summary>
        /// converts stream to bytearray for resized image
        /// </summary>
        /// <param name="MaxSideSize"></param>
        /// <param name="Buffer"></param>
        /// <returns></returns>
        public static byte[] ResizeFromStream(int MaxSideSize, Stream Buffer, string fileName)
        {
            byte[] byteArray = null;  // really make this an error gif

            try
            {

                Bitmap bitMap = new Bitmap(Buffer);
                int intOldWidth = bitMap.Width;
                int intOldHeight = bitMap.Height;

                int intNewWidth;
                int intNewHeight;

                int intMaxSide;

                if (intOldWidth >= intOldHeight)
                {
                    intMaxSide = intOldWidth;
                }
                else
                {
                    intMaxSide = intOldHeight;
                }

                if (intMaxSide > MaxSideSize)
                {
                    //set new width and height
                    double dblCoef = MaxSideSize / (double)intMaxSide;
                    intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
                    intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
                }
                else
                {
                    intNewWidth = intOldWidth;
                    intNewHeight = intOldHeight;
                }

                Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
                System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
                System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);

                Graphics oGraphic = Graphics.FromImage(oThumbNail);
                oGraphic.CompositingQuality = CompositingQuality.HighQuality;
                oGraphic.SmoothingMode = SmoothingMode.HighQuality;
                oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle oRectangle = new Rectangle
                    (0, 0, ThumbNailSize.Width, ThumbNailSize.Height);

                oGraphic.DrawImage(oImg, oRectangle);

                MemoryStream ms = new MemoryStream();
                oThumbNail.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                oGraphic.Dispose();
                oImg.Dispose();
                ms.Close();
                ms.Dispose();
            }
            catch (Exception)
            {
                int newSize = MaxSideSize - 20;
                Bitmap bitMap = new Bitmap(newSize, newSize);
                Graphics g = Graphics.FromImage(bitMap);
                g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));

                Font font = new Font("Courier", 8);
                SolidBrush solidBrush = new SolidBrush(Color.Red);
                g.DrawString("Failed File", font, solidBrush, 10, 5);
                g.DrawString(fileName, font, solidBrush, 10, 50);

                MemoryStream ms = new MemoryStream();
                bitMap.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                ms.Close();
                ms.Dispose();
                bitMap.Dispose();
                solidBrush.Dispose();
                g.Dispose();
                font.Dispose();

            }
            return byteArray;
        }

        /// <summary>
        /// Saves the resized image to specified file name and path as JPEG
        /// and also returns the bytearray for any other use you may need it for
        /// </summary>
        /// <param name="MaxSideSize"></param>
        /// <param name="Buffer"></param>
        /// <param name="fileName">No Extension</param>
        /// <param name="filePath">Examples: "images/dir1/dir2" or "images" or "images/dir1"</param>
        /// <returns></returns>
        public static byte[] SaveFromStream(int MaxSideSize, Stream Buffer, string fileName, string filePath)
        {
            byte[] byteArray = null;  // really make this an error gif

            try
            {

                Bitmap bitMap = new Bitmap(Buffer);
                int intOldWidth = bitMap.Width;
                int intOldHeight = bitMap.Height;

                int intNewWidth;
                int intNewHeight;

                int intMaxSide;

                if (intOldWidth >= intOldHeight)
                {
                    intMaxSide = intOldWidth;
                }
                else
                {
                    intMaxSide = intOldHeight;
                }

                if (intMaxSide > MaxSideSize)
                {
                    //set new width and height
                    double dblCoef = MaxSideSize / (double)intMaxSide;
                    intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
                    intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
                }
                else
                {
                    intNewWidth = intOldWidth;
                    intNewHeight = intOldHeight;
                }

                Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
                System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
                System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);

                Graphics oGraphic = Graphics.FromImage(oThumbNail);
                oGraphic.CompositingQuality = CompositingQuality.HighQuality;
                oGraphic.SmoothingMode = SmoothingMode.HighQuality;
                oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle oRectangle = new Rectangle
                    (0, 0, ThumbNailSize.Width, ThumbNailSize.Height);

                oGraphic.DrawImage(oImg, oRectangle);

                //Save File
                string newFileName = string.Format(System.Web.HttpContext.Current.Server.MapPath("~/{0}/{1}.jpg"), filePath, fileName);
                oThumbNail.Save(newFileName, ImageFormat.Jpeg);

                MemoryStream ms = new MemoryStream();
                oThumbNail.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                oGraphic.Dispose();
                oImg.Dispose();
                ms.Close();
                ms.Dispose();
            }
            catch (Exception)
            {
                int newSize = MaxSideSize - 20;
                Bitmap bitMap = new Bitmap(newSize, newSize);
                Graphics g = Graphics.FromImage(bitMap);
                g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));

                Font font = new Font("Courier", 8);
                SolidBrush solidBrush = new SolidBrush(Color.Red);
                g.DrawString("Failed To Save File or Failed File", font, solidBrush, 10, 5);
                g.DrawString(fileName, font, solidBrush, 10, 50);

                MemoryStream ms = new MemoryStream();
                bitMap.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                ms.Close();
                ms.Dispose();
                bitMap.Dispose();
                solidBrush.Dispose();
                g.Dispose();
                font.Dispose();

            }
            return byteArray;
        }
	}
}



